<?php
/**
 * Created by PhpStorm.
 * User: 丶晓
 * Date: 2017/9/22
 * Time: 17:12
 */

namespace app\api\service;


use Yansongda\Pay\Pay;
use think\Config;
use think\Request;
use think\Session;
use app\common\Base;
use app\api\model\PayModel;

class PayService extends PayModel
{
    private $nonce_str;
    protected $batchquerycomment = 'https://api.mch.weixin.qq.com/billcommentsp/batchquerycomment'; // 拉取订单评价数据

    public function __construct(Request $request = null)
    {
        parent::__construct();
        $this->nonce_str = Session::get('payToken');
    }

    public function payProcess($type, $data)
    {
        if (empty($type) or empty($data)) {
            return false;
        }
        switch ($type) {
            case 'create_miniapp_order':
                return $this->addInfo('ready_miniapps', $data);
                break;
            case 'ready_buy_template_alipay':
                $pay_id = $this->addInfo('ready_alipay', $data);
                if ($pay_id and $this->changeInfo('ready_buyTemplate', ['id' => $data['order_id'], 'ali_pay_id' => $pay_id])) {
                    return true;
                }
                break;
            case 'ready_pay_recharge_alipay':
                $pay_id = $this->addInfo('ready_alipay', $data);
                if ($pay_id and $this->changeInfo('ready_payRecharge', ['id' => $data['order_id'], 'ali_pay_id' => $pay_id])) {
                    return true;
                }
                break;
            case 'ready_buy_template_wechat':
                $pay_id = $this->addInfo('ready_wechat', $data);
                if ($pay_id and $this->changeInfo('ready_buyTemplate', ['id' => $data['order_id'], 'wechat_pay_id' => $pay_id])) {
                    return true;
                }
                break;
            case 'ready_pay_recharge_wechat':
                $pay_id = $this->addInfo('ready_wechat', $data);
                if ($pay_id and $this->changeInfo('ready_payRecharge', ['id' => $data['order_id'], 'wechat_pay_id' => $pay_id])) {
                    return true;
                }
                break;
        }
        return false;
    }

    public function alipayReturn($request)
    {
        $config = [
            'alipay' => [
                'app_id' => Config::get('alipay.app_id'),
                'notify_url' => Config::get('alipay.notify_url'),
                'return_url' => Config::get('alipay.return_url'),
                'ali_public_key' => Config::get('alipay.public_key'),
                'private_key' => Config::get('alipay.private_key'),
            ]
        ];
        $pay = new Pay($config);
        return $pay->driver('alipay')->gateway()->verify($request);
    }

    public function wechatPayReturn($request, $gateway)
    {
        $config = [
            'wechat' => [
                'app_id' => Config::get('wechat.mp_appid'),
                'mch_id' => Config::get('wechatPay.mch_id'),
                'notify_url' => Config::get('wechatPay.notify_url'),
                'key' => Config::get('wechatPay.key'),
                'cert_client' => Config::get('wechatPay.cert_client'),
                'cert_key' => Config::get('wechatPay.cert_key')
            ],
        ];
        $pay = new Pay($config);
        return $pay->driver('wechat')->gateway($gateway)->verify($request);
    }

    public function signPay($driver = 'wechat', $type = 'scan', $parms = [])
    {
        $drivers = $driver . '_' . $type;  // 指定类型
        switch ($drivers) {
            case 'alipay_scan':
                $config = [
                    'alipay' => [
                        'app_id' => Config::get('alipay.app_id'),
                        'notify_url' => Config::get('alipay.notify_url'),
                        'ali_public_key' => Config::get('alipay.public_key'),
                        'private_key' => Config::get('alipay.private_key'),
                    ],
                ];
                $config_biz = [
                    'out_trade_no' => $parms['out_trade_no'],   // 订单号
                    'total_amount' => $parms['price'],    // 订单金额，单位：元
                    'subject' => $parms['source'],        // 订单商品标题
                    'body' => $parms['describe']          // 订单描述
                ];
                break;
            case 'wechat_scan':
                $config = [
                    'wechat' => [
                        'app_id' => Config::get('wechat.mp_appid'),            // 微信公众号 APPID
                        'mch_id' => Config::get('wechatPay.mch_id'),           // 微信商户号
                        'notify_url' => Config::get('wechatPay.notify_url'),   // 异步地址
                        'key' => Config::get('wechatPay.key'),                 // 微信支付签名秘钥
                        'cert_client' => Config::get('wechatPay.cert_client'), // 客户端证书路径，退款时需要用到
                        'cert_key' => Config::get('wechatPay.cert_key')        // 客户端秘钥路径，退款时需要用到
                    ],
                ];
                $config_biz = [
                    'out_trade_no' => $parms['out_trade_no'],           // 订单号
                    'total_fee' => $parms['price'] * 100,               // 订单金额
                    'body' => $parms['source'],                         // 订单描述
                    'spbill_create_ip' => Request::instance()->ip(),    // 调用 API 服务器的 IP
                    'product_id' => 'suYong-SCAN',                       // 订单商品 ID
                    'detail' => $parms['describe']
                ];
                break;
            case 'wechat_miniapp':
                $config = [
                    'wechat' => [
                        'miniapp_id' => $parms['miniapp_id'],            // 微信公众号 APPID
                        'mch_id' => $parms['mch_id'],           // 微信商户号
                        'notify_url' => Config::get('wechatPay.miniapp_notify_url'),   // 异步地址
                        'key' => $parms['key'],               // 微信支付签名秘钥
                        'cert_client' => $parms['cert_client'], // 客户端证书路径，退款时需要用到
                        'cert_key' => $parms['cert_key']        // 客户端秘钥路径，退款时需要用到
                    ],
                ];
                $config_biz = [
                    'out_trade_no' => $parms['out_trade_no'],          // 订单号
                    'total_fee' => $parms['total_fee'] * 100,          // 订单金额
                    'body' => $parms['body'],                          // 订单描述
                    'spbill_create_ip' => Request::instance()->ip(),   // 调用 API 服务器的 IP
                    'openid' => $parms['openid']
                ];
                break;
            default:
                return false;
                break;
        }
        $Pay = new Pay($config);
        return $Pay->driver($driver)->gateway($type)->pay($config_biz);
    }

    public function wechatPaySign($key, $data, $way = 'sha256')
    {
        ksort($data);
        $stringA = urldecode(http_build_query($data));
        $stringSignTemp = $stringA . "&key=" . $key;
        return strtoupper(hash_hmac($way, $stringSignTemp, $key));
    }

    /* 已废弃 */
    public function checkMchPayFile($data)
    {
        $appid = $data['appid'];
        $mch_id = $data['mch_id'];
        $secret = $data['secret'];
        $cert = $data['cert'];
        $key = $data['key'];

        if (empty($appid) or empty($mch_id) or empty($secret) or empty($cert) or empty($key)) {
            return false;
        }

        $nonce_str = $this->nonce_str;
        $begin_time = date('Ymd', strtotime("-1 day")) . '000000';
        $end_time = date('Ymd') . '000000';
        $postArr = [
            'appid' => $appid,
            'mch_id' => $mch_id,
            'nonce_str' => $nonce_str,
            'begin_time' => $begin_time,
            'end_time' => $end_time,
            'offset' => 0,
            'limit' => 100,
        ];
        $base = new Base();
        $postArr['sign'] = $base->wechatPaySign($secret, $postArr);
        $RES = $base->_requestPost($this->batchquerycomment, $base->toXml($postArr), ['cert' => ROOT_PATH . $cert, 'key' => ROOT_PATH . $key]);
        $postObj = simplexml_load_string($RES, 'SimpleXMLElement', LIBXML_NOCDATA);
        if ($postObj->return_code == 'SUCCESS') {
            return true;
        }
        return false;
    }

    public function saveMchPayFile($data)
    {
//        if (!$this->checkMchPayFile($data)) {
//            return false;
//        }
        return $this->changeInfo('mchPayFile', $data);
    }
}